/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.seguranca.facade;

import br.uniceub.fsw.seguranca.bo.UsuarioBO;
import br.uniceub.fsw.seguranca.dao.UsuarioDAO;
import br.uniceub.fsw.util.HttpRequestWithModifiableParameters;
import br.uniceub.fsw.seguranca.vo.UsuarioVO;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Facade de execução do login.
 * Serve como interface de acesso à camada de dados e
 * implementa a camada de negócio da aplicação.
 * 
 * @author Bruno Schifer Bernardi
 */
public class LoginFacade {
    /**
     * Nome do último nível.
     */
    public static final String ultimoNivel = "fswuniceub";

    /**
     * Mensagem de retorno do sistema.
     */
    private String message;
    
    /**
     * Flag que indica se o usuário está logado.
     */
    private boolean logado;
    
    /**
     * Flag que indica se o usuário tem acesso ao módulo.
     */
    private boolean temAcesso;
    
    /**
     * Objeto de acesso aos dados da entidade Usuario.
     */
    private UsuarioDAO usuarioDao;
    
    /**
     * Construtor da classe.
     */
    public LoginFacade() {
        this.usuarioDao = new UsuarioDAO();
    }

    /**
     * Getter da flag temAcesso
     * 
     * @return Flag indicando se o usuário tem acesso ao módulo.
     */
    public boolean possuiAcesso() {
        return this.temAcesso;
    }
    
    /**
     * Setter da flag temAcesso
     * 
     * @param temAcesso Flag indicando se o usuário tem acesso ao módulo.
     */
    public void setTemAcesso(boolean temAcesso) {
        this.temAcesso = temAcesso;
    }
    
    /**
     * Getter da flag logado.
     * 
     * @return Flag indicando se o usuário está logado.
     */
    public boolean estaLogado() {
        return logado;
    }

    /**
     * Setter da flag logado.
     * 
     * @param estaLogado Flag indicando se o usuário está logado.
     */
    public void setLogado(boolean logado) {
        this.logado = logado;
    }

    /**
     * Getter da mensagem de retorno.
     * 
     * @return Mensagem de retorno.
     */
    public String getMessage() {
        String retorno = null;
        if(this.message == null || this.message.equals("")) {
            retorno = "&nbsp";
        } else {
            retorno = this.message;
        }
        return retorno;
    }

    /**
     * Setter da mensagem de retorno.
     * 
     * @param message Mensagem de retorno.
     */
    public void setMessage(String message) {
        this.message = message;
    }

    /**
     * Responsável por executar a operação selecionada pelo usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void operacao(HttpServletRequest req, HttpServletResponse resp) {
        String oper = req.getParameter("operacao");

        if(oper != null)
        {
            if (oper.equals("autenticar")) {
                this.autenticar(req, resp);
            }
            if (oper.equals("sair")) {
                this.message = "Logout de usu&aacute;rio executado.";
            }
        }
    }
    
    /**
     * Autentica um usuário no sistema.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void autenticar(HttpServletRequest req, HttpServletResponse resp) {
        // Busca parametros da tela
        String login = req.getParameter("noUsuario");
        String senha = req.getParameter("psSenha");
        
        UsuarioVO usuario = new UsuarioVO();
        
        usuario.setNoUsuario(login);
        usuario.setDsSenha(senha);
        
        UsuarioBO usuarioBO = new UsuarioBO();
        
        try {
            usuarioBO.validarFormLogin(usuario);
        } catch (Exception ex) {
            this.message = ex.getMessage();
        }

        if(this.message == null || this.message.trim().length() == 0) {
            UsuarioFacade usuarioFacade = new UsuarioFacade();

            String senhaCriptografada = usuarioFacade.criptografar(senha);

            usuario.setDsSenha(senhaCriptografada);

            List<UsuarioVO> listaRetorno = this.usuarioDao.consultarPorExemplo(usuario);

            UsuarioVO usuarioAutenticado = null;
            if(listaRetorno.size() > 0) {
                usuarioAutenticado = listaRetorno.get(0);
            }

            // Usuário não cadastrado ou erro de login
            if(usuarioAutenticado == null) {
                this.message = "Login inv&aacute;lido.";
                return;
            }

            req.getSession().setAttribute("SESSION_USER", usuarioAutenticado);

            RequestDispatcher rd = req.getRequestDispatcher("/gestao/construirMenu/construirMenu.jsp");
            try {
                rd.forward(req, resp);
            } catch (Exception ex) {
                System.out.println("LoginFacade.autenticar() - Ex: " + ex.getMessage());
            }
        } else {
            RequestDispatcher rd = req.getRequestDispatcher("/gestao/efetuarLogin/efetuarLogin.jsp");
            try {
                rd.forward(req, resp);
            } catch (Exception ex) {
                System.out.println("LoginFacade.autenticar() - Ex: " + ex.getMessage());
            }
        }
    }
    
    /**
     * Verifica se o usuário está logado no sistema.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void verificarLogin(HttpServletRequest req, HttpServletResponse resp) {
        UsuarioVO usuario = (UsuarioVO) req.getSession().getAttribute("SESSION_USER");
        
        if(usuario == null) {
            this.message = "Usu&aacute;rio n&atilde;o est&aacute; autenticado.";
            this.logado = false;
            return;
        }
        
        this.logado = true;
    }

    /**
     * Verifica se o usuário possui acesso ao
     * módulo em questão.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void verificarAcesso(HttpServletRequest req, HttpServletResponse resp) {
        UsuarioVO usuario = (UsuarioVO) req.getSession().getAttribute("SESSION_USER");

        if(usuario != null) {
            String modulo = null;
            
            String url = req.getRequestURL().toString();
            
            String[] lista = url.split("/");
            
            int tamanho = lista.length;
            
            boolean acesso = true;
            
            for(int i = tamanho; i > 0; i--) {
                modulo = lista[i - 2];

                if(modulo.equals(ultimoNivel)) {
                    break;
                }

                UsuarioVO usuarioComAcesso = usuarioDao.consultarUmPorModuloPorIdUsuario(modulo, usuario.getIdUsuario());
                
                if(usuarioComAcesso == null) {
                    acesso = false;
                    break;
                }
            }
            
            if(!acesso) {
                this.message = "Usu&aacute;rio sem acesso ao m&oacute;dulo.";
                this.temAcesso = false;
                return;
            }
        }
        else {
            return;
        }

        this.temAcesso = true;
    }
    
    /**
     * Controla tanto o acesso de usuário não autenticado quanto de
     * usuário autenticado sem acesso ao módulo.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void controlarAcesso(HttpServletRequest req, HttpServletResponse resp) {
        this.verificarAcesso(req, resp);
        this.verificarLogin(req, resp);
        
        if(!this.logado || !this.temAcesso) {
            RequestDispatcher rd = req.getRequestDispatcher("/gestao/seguranca/controlarAcesso/controlarAcesso.jsp");
            try {
                HttpRequestWithModifiableParameters wrapper = new HttpRequestWithModifiableParameters(req);
                
                wrapper.setParameter("mensagem", this.message);
                
                rd.forward(wrapper, resp);
            } catch (Exception ex) {
                System.out.println("LoginFacade.controlarAcesso() - Ex: " + ex.getMessage());
            }
        }
    }
    
    /**
     * Recebe a mensagem de retorno do sistema e devolve ela para a tela.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     * @return Mensagem de retorno do sistema.
     */
    public String receberMensagem(HttpServletRequest req, HttpServletResponse resp) {
        this.message = req.getParameter("mensagem");
        
        String retorno = this.getMessage();
        
        return retorno;
    }
    
    /**
     * Retorna o id do usuário logado
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     * @return Id do usuário logado.
     */
    public Integer pegarIdUsuario(HttpServletRequest req, HttpServletResponse resp) {
        UsuarioVO usuario = (UsuarioVO) req.getSession().getAttribute("SESSION_USER");
        
        if(usuario == null) {
            return null;
        }
        
        return usuario.getIdUsuario();
    }
    
    public Integer pegarCdTalento(HttpServletRequest req, HttpServletResponse resp) {
        UsuarioVO usuario = (UsuarioVO) req.getSession().getAttribute("SESSION_USER");
        
        if(usuario == null) {
            return null;
        }
        
        return usuario.getCdTalento();
    }
    
}
